package com.ebo.httpcall4j.core.rerun;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.ebo.httpcall4j.core.ApplicationContextHolder;
import com.ebo.httpcall4j.core.HttpCallService;
import com.ebo.httpcall4j.core.log.HttpCallLogService;
import com.ebo.httpcall4j.core.model.HttpCallLog;
import com.ebo.httpcall4j.core.model.HttpCallRequest;
import com.ebo.httpcall4j.core.model.HttpCallResponse;
import com.ebo.httpcall4j.core.model.enums.HttpMethod;
import com.ebo.httpcall4j.core.processor.HttpCallProcessor;
import com.ebo.httpcall4j.core.repository.HttpCallLogRepository;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.Optional;

/**
 * http调用重试服务
 */
@Service
public class HttpCallRerunService {

    private final HttpCallLogRepository logRepository;
    private final HttpCallService httpCallService;
    private final HttpCallLogService logService;
    private final ApplicationContext applicationContext;

    public HttpCallRerunService(HttpCallLogRepository logRepository, HttpCallService httpCallService, HttpCallLogService logService) {
        this.logRepository = logRepository;
        this.httpCallService = httpCallService;
        this.logService = logService;
        applicationContext = ApplicationContextHolder.getContext();

    }

    /**
     * 根据日志ID重试失败的HTTP调用
     *
     * @param logId 原始日志ID
     * @return 新的HttpCallResponse
     * @throws IOException
     */
    public HttpCallResponse rerun(Long logId) throws IOException {
        Optional<HttpCallLog> logOptional = logRepository.findById(logId);
        if (!logOptional.isPresent()) {
            throw new IllegalArgumentException("Log not found with id: " + logId);
        }

        HttpCallLog originalLog = logOptional.get();

        HttpCallRequest request = new HttpCallRequest();
        request.setUrl(originalLog.getUrl());
        request.setMethod(HttpMethod.valueOf(originalLog.getMethod()));
        request.setBody(originalLog.getBody());
        request.setSystemName(originalLog.getSystemName());
        request.setFunctionName(originalLog.getFunctionName());
        request.setLogEnabled(false);

        Map<String, String> headers = JSONObject.parseObject(originalLog.getHeaders(), new TypeReference<Map<String, String>>() {
        });
        request.setHeaders(headers);

        HttpCallResponse response;
        try {
            HttpCallProcessor processor = applicationContext.getBean(originalLog.getProcessorName(), HttpCallProcessor.class);
            response = httpCallService.call(request, processor.getClass());
            request.setLogEnabled(true);
            logService.log(originalLog.getProcessorName(), request, response, response.isSuccess(), logId);
        } catch (IOException e) {
            logService.logException(originalLog.getProcessorName(), request, e, logId);
            throw e;
        }

        return response;
    }
}